<?php
namespace app\admin\controller;

use app\BaseController;
use think\App;
use think\exception\HttpResponseException;
use think\exception\ValidateException;
use think\facade\View;
use think\Request;
use think\facade\Session;
use think\Response;

class Common extends BaseController
{
    protected $admin;
    protected $admin_id;

    // 模型
    protected $modelClass;
    // 关联模型
    protected $withModel = [];
    // 详情 - 关联模型
    protected $detailWithModel = [];
    // 验证器
    protected $validator;

    // 实例化之后的模型对象
    protected $model;
    // 参数
    protected $request_data;

    // 视图渲染的页面路径
    protected $view_page;

    protected $middleware = [
        'admin.auth',
        'admin.rabc',
        'admin.log',
    ];

    // 允许访问的方法。开启的方法【如果设置了，那么不存在这个变量内部的方法全部不允许访问；否则只需检测 $forbidden_method 即可】
    protected $public_method = [];

    // 禁用的方法【如果设置了，那么存在这个变量内部的方法全部不允许访问；否则只需检测 $public_method 即可】
    protected $forbidden_method = [];

    public function __construct(App $app)
    {
        parent::__construct($app);

        // 检测当前方法是否允许访问：允许访问与禁止方法，只允许设置一项！
        $forbidden = false;
        if (!empty($this->public_method) || !empty($this->forbidden_method)){
            if (!empty($this->public_method)){
                if (!in_array($app->request->action(), $this->public_method)){
                    $forbidden = true;
                }
            }else{
                if (in_array($app->request->action(), $this->forbidden_method)){
                    $forbidden = true;
                }
            }
        }
        if ($forbidden){
            if ($this->request->isPost()){
                $response = Response::create( [
                    'status' => 0,
                    'msg' => '禁止访问！',
                    'data' => [],
                ], $this->getResponseType());
                throw new HttpResponseException($response);
            }else{
                $this->error('禁止访问！');
            }
        }

        // 检测登录管理员的基本信息
        $this->admin = getLoginAdmin();
        // 加载完 __construct之后，才会加载控制器的中间件
        if ($this->admin){
            View::assign('admin', $this->admin);
            // 设置登录管理员的Id
            $this->admin_id = getLoginAdminId();
            // 实例化模型
            if ( !empty($this->modelClass) ) {
                $this->model = $this->modelClass::getInstance();
            }

            // 公共参数
            $this->request_data = $this->getFilterRequest(input());

            // 左侧的菜单栏目
            if ($left_menus = Session::get('login_admin_menus')){
            }else{
                $left_menus = $this->admin->role->menus->where('is_left', 1)->order('menu_sort', 'ASC')->toArray();
                Session::set('login_admin_menus', $left_menus);
            }
            $left_menus = \app\admin\model\Admins::find($this->admin->admin_id)->role->menus->where('is_left', 1)->order('menu_sort', 'ASC')->toArray();
            View::assign('left_menus', list_to_tree($left_menus));
            // 当前路由
            $controller = $app->request->controller(true);
            View::assign('route', $controller . '/' . $app->request->action());
            // 当前控制器
            View::assign('controller', $controller);
        }

        // 视图渲染的页面
        $this->view_page = cnpscy_config('admin_template') . '/' . $this->request->controller(true) . '/' . $this->request->action();
    }

    protected function getFilterRequest(array $request_data = [])
    {
        $request_data['is_check'] = intval($request_data['is_check'] ?? -1);
        $request_data['search'] = trim($request_data['search'] ?? '');
        $request_data['limit'] = intval($request_data['limit'] ?? 10);
        if ($request_data['limit'] == 0 || !is_numeric($request_data['limit'])) $request_data['limit'] = 10;
        $request_data['where'] = [];
        return $request_data;
    }

    protected function setSearchWhereFilter(array &$params = []) : void
    {

    }

    /**
     * 显示资源列表
     *
     * @return \think\Response
     */
    public function index()
    {
        if ($this->model) {
            // Search搜索与筛选条件
            if (method_exists($this, 'setSearchWhereFilter')) $this->setSearchWhereFilter($this->request_data);

            // 关联查询
            $this->request_data['withModel'] = $this->withModel;

            $list = $this->model->getPaginate($this->request_data);
        }else{
            $list = [];
        }
//        var_dump($list->toArray()['data']);
//        exit;
        return view($this->view_page, compact('list'));
    }

    /**
     * 显示编辑资源表单页.
     *
     * @param  int  $id
     * @return \think\Response
     */
    public function detail()
    {
        $id = input($this->model->getPk(), 0);
        if ($id){
            $detail = $this->model->detail($id, '*', false, $this->detailWithModel);
        }else{
            $detail = [];
        }
//        var_dump($detail->toArray());
//        exit;
        return view($this->view_page, compact('detail', 'id'));
    }

    /**
     * 保存新建的资源
     *
     * @param  \think\Request  $request
     * @return \think\Response
     */
    public function create(Request $request)
    {
        if (!$request->isPost()){
            return $this->errorJson('非法请求！');
        }
        $params = $request->param();
        if ($this->validator){
            try {
                validate($this->validator)->scene(__FUNCTION__)->check($params);
            } catch (ValidateException $e) {
                // 验证失败 输出错误信息
                return $this->errorJson($e->getMessage());
            }
        }

        if ($res = $this->model->add($params)){
            return $this->successJson($res, $this->model->getError());
        }else{
            return $this->errorJson($this->model->getError());
        }
    }

    /**
     * 保存更新的资源
     *
     * @param  \think\Request  $request
     * @param  int  $id
     * @return \think\Response
     */
    public function update(Request $request)
    {
        if (!$request->isPost()){
            return $this->errorJson('非法请求！');
        }
        if (!$request->param($this->model->getPK(), 0)){
            return $this->create($request);
        }
        $params = $request->param();
        if ($this->validator) {
            try {
                validate($this->validator)->scene(__FUNCTION__)->check($params);
            } catch (ValidateException $e) {
                // 验证失败 输出错误信息
                return $this->errorJson($e->getMessage());
            }
        }
        if ($res = $this->model->edit($params)){
            return $this->successJson($res, $this->model->getError());
        }else{
            return $this->errorJson($this->model->getError());
        }
    }

    public function changeFiledStatus(Request $request)
    {
        if ($res = $this->model->changeFiledStatus($request->param())){
            return $this->successJson($res, $this->model->getError());
        }else{
            return $this->errorJson($this->model->getError());
        }
    }

    /**
     * 删除指定资源
     *
     * @param  int  $id
     * @return \think\Response
     */
    public function delete(Request $request)
    {
        if (!$request->isPost()){
            return $this->errorJson('非法请求！');
        }
        if ($res = $this->model->dataDelete($request->param())){
            return $this->successJson($res, $this->model->getError());
        }else{
            return $this->errorJson($this->model->getError());
        }
    }

    public function export(string $file_name = '',array $title = [],array $data = [])
    {
        // PHP脚本执行的最长时间
        ini_set('max_execution_time', 0);//秒为单位，自己根据需要定义
        // 内存大小
        ini_set('memory_limit', -1);

        // 如果标题为空，那么自动展示数据表结构
        if (empty($title)){
            $title = $this->model->db(false)
                                 ->getConnection()
                                 ->getTableFields($this->model->getTable());
        }

        if (empty($data)) $data = $this->model->deleteWhere()->field($title)->order($this->model->getPk(), 'DESC')->select()->toArray() ?? [];

        if ( empty($file_name) ) $file_name = '导出表格';
        $file_name .= ' - ' . date('Ymdhis') . '.xlsx';
        // 文件名不可以出现空格，否则导出的表格无法打开
        $file_name = str_replace(' ', '', $file_name);


        export_excel($file_name, $title, $data);
        exit;
        $this->download($file_name, $title, $data);
    }
}